package org.wedding.center.util;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 分布式订单码生成器
 *
 * @author songkaiyue
 * @since 2025-05-16 10:42:50
 */
public class RedemptionCodeGenerator {
    // 机器标识（部署时配置）
    private static final String MACHINE_ID = "A1"; // 2位大写字母/数字
    // 序列号（每分钟重置）
    private static final AtomicInteger sequence = new AtomicInteger(0);
    // 时间戳缓存（分钟级）
    private static volatile long lastMinute = 0;

    /**
     * 生成订单核销码
     *
     * @return
     */
    public static String generate(List<String> codes) {
        // 1. 获取当前时间戳（分钟级）
        final long currentMinute = Instant.now().getEpochSecond() / 60;

        // 2. 每分钟重置序列号
        synchronized (RedemptionCodeGenerator.class) {
            if (currentMinute != lastMinute) {
                sequence.set(0);
                lastMinute = currentMinute;
            }
        }

        // 3. 生成组件
        final int seq = sequence.getAndIncrement();
        final String timeCode = encodeBase36(currentMinute, 4); // 4位时间编码（约3.2年周期）
        final String seqCode = encodeBase36(seq, 4);           // 4位序列编码

        // 4. 组合核销码（4+2+4=10位）
        String code = timeCode + MACHINE_ID + seqCode;
        if (!codes.isEmpty()) {
            if (codes.contains(code)) {
                code = generate(codes);
            }
        }
        return code;
    }

    /**
     * 将数字转换为固定长度的Base36编码（大写）
     *
     * @param number 输入数字
     * @param length 输出长度
     */
    private static String encodeBase36(long number, int length) {
        String code = Long.toString(number, 36).toUpperCase();
        return String.format("%" + length + "s", code)
                .replace(' ', '0')
                .substring(0, length);
    }

    /**
     * 生成订单编号
     *
     * @return
     */
    public static String getCode() {
        LocalDateTime now = LocalDateTime.now();
        return "ORDER" +
                now.format(DateTimeFormatter.ofPattern("HHmmss")).substring(1) + // 5位时间
                MACHINE_ID +                                                      // 2位机器ID
                String.format("%02d", sequence.getAndIncrement() % 100);          // 2位序列
    }
    /**
     * 生成尾款订单编号
     *
     * @return
     */
    public static String getWkCode() {
        LocalDateTime now = LocalDateTime.now();
        return "ORDERWK" +
                now.format(DateTimeFormatter.ofPattern("HHmmss")).substring(1) + // 5位时间
                MACHINE_ID +                                                      // 2位机器ID
                String.format("%02d", sequence.getAndIncrement() % 100);          // 2位序列
    }
//    public static void main(String[] args) {
//        // 示例输出：WED21094578（假设当前时间21日09:45，序列78）
//        for (int i = 0; i < 5; i++) {
//            System.out.println(RedemptionCodeGenerator.generate());
//        }
//    }
}
